﻿namespace Glass
{
    using System;
    using System.Linq;
    using System.Threading;

    using Ecng.Common;

    using StockSharp.BusinessEntities;
    using StockSharp.Quik;
    using StockSharp.Algo;
    using System.Data;
    using System.Collections.Generic;
   

    using Ecng.Collections;

    // using System.Linq;

    class Glass
    {
        private static Security _sec1, _sec2;
        //private static Portfolio _portfolio;
        private static MarketDepth _depth, _depth2;


        static void Main()
        {
            try
            {
                //if () {
                // для теста выбираем бумагу Лукойл
                //string secCode1 = "LKZ1";
                //int Vol1 = 99;
               // string secCode = "SRZ1";
              //  int VolsecCode = 2500;

                string secCode = "SRH2";
                int VolsecCode = 2500;

                //DataTable seccodes1 = new DataTable();
                //seccodes1.Columns.Add("seccode", typeof(string));
                //seccodes1.Columns.Add("vol", typeof(int));
                //seccodes1.Rows.Add("BRX1", 200);
                //seccodes1.Rows.Add("SRZ1", 1200);


                //DataTable signals1 = new DataTable();

                //signals1.Columns.Add("id", typeof(int));
                //signals1.Columns.Add("seccode", typeof(string));
                //signals1.Columns.Add("vol", typeof(decimal));
                //signals1.Columns.Add("date", typeof(string));
                //signals1.Columns.Add("time", typeof(string));
                //signals1.Columns.Add("vector", typeof(decimal));
                //signals1.Columns.Add("vector", typeof(decimal));


                var quikPath = QuikTerminal.GetDefaultPath();

                if (quikPath.IsEmpty())
                {
                    Console.WriteLine("Не найден ни один запущенный Quik");
                    return;
                }

                Console.WriteLine("Запущенный Quik найден по пути " + quikPath);

                //Console.Write("Введите код клиента, через который будет выставлена заявка: ");
                // var account = "SPBFUT0041M";//Console.ReadLine();

                using (var waitHandle = new AutoResetEvent(false))
                {
                    // создаем шлюз к Quik-у
                    using (var trader = new QuikTrader(quikPath))
                    {
                        // подписываемся на событие успешного подключения
                        // все действия необходимо производить только после подключения

                        trader.Connected += () => // после теста рем удалить
                        {    // после теста рем удалить
                            Console.WriteLine("Подключение было произведено успешно.");
                            // извещаем об успешном соединени
                            waitHandle.Set();
                        };  // после теста рем удалить
                        //Console.WriteLine("Производим подключение...");

                        trader.Connect();

                        // дожидаемся события об успешном соединении
                        waitHandle.WaitOne();



                        // подписываемся на событие появление инструментов
                        trader.NewSecurities += securities =>
                        {
                            if ((_sec1 == null) || (_sec2 == null))
                            {
                                //if (_sec1 == null) _sec1 = securities.FirstOrDefault(sec => sec.Code == secCode1);
                                if (_sec2 == null) _sec2 = securities.FirstOrDefault(sec => sec.Code == secCode);

                                //if (_sec1 != null) trader.RegisterQuotes(_sec1);// запускаем экспорт стакана      
                                if (_sec2 != null) trader.RegisterQuotes(_sec2);// запускаем экспорт стакана
                            }
                        };

                        // подписываемся на событие обновления стакана
                        trader.QuotesChanged += depths =>
                        {
                            //if ((_depth == null || _depth2 == null) && (_sec1 != null || _sec2 != null))
                            if ((_depth2 == null) && (_sec2 != null))
                            {
                                if (_depth2 == null && _sec2 != null) _depth2 = depths.FirstOrDefault(d => d.Security == _sec2);
                                // if (_depth == null && _sec1 != null) _depth = depths.FirstOrDefault(d => d.Security == _sec1);

                                //if ((_depth != null) && (_depth2 != null))
                                if (_depth2 != null)
                                {
                                    //Console.WriteLine("Стакан {0} появился.", _sec1);
                                    Console.WriteLine("Стакан {0} появился.", _sec2);
                                    waitHandle.Set();
                                }
                            }
                        };

                        //Console.WriteLine("Дожидаемся появления в программе инструмента Лукойл и портфеля {0}...".Put(account));

                        // запускаем экспорт по DDE
                        //trader.StartExport(trader.SecuritiesTable, trader.MyTradesTable, trader.EquityPositionsTable, trader.EquityPortfoliosTable, trader.OrdersTable);

                        //trader.SecuritiesTable.Columns.Add(DdeSecurityColumns.Volatility);
                        trader.StartExport(trader.SecuritiesTable);
                        

                        // дожидаемся появления портфеля и инструмента
                        waitHandle.WaitOne();

                        string short_long;

                        //подключаем MySQL

                        MySql.Data.MySqlClient.MySqlConnection conn;
                        MySql.Data.MySqlClient.MySqlCommand cmd;
                        //MySql.Data.MySqlClient

                        conn = new MySql.Data.MySqlClient.MySqlConnection();
                        cmd = new MySql.Data.MySqlClient.MySqlCommand();
                        //myAdapter = new MySql.Data.MySqlClient.MySqlDataAdapter();

                        conn.ConnectionString = "server=92.255.251.110;uid=ast;pwd=7hxSAYcrYCjn7nb5;database=pager;";
                        //conn.ConnectionString = "server=localhost;uid=ast;pwd=7hxSAYcrYCjn7nb5;database=pager;";
                        cmd.Connection = conn;
                        conn.Open();

                        //DateTime date = DateTime.Today; //текущая дата
                        //DateTime StartTime = DateTime.("23:59:00",date); // время начала работы биржи
                        //DateTime FinishTime = DateTime.Now.AddHours(24); // время окончания работы биржи
                        //int date = Convert.ToInt32(DateTime.Now.ToString("yyyyMMdd")); //текущая дата
                        string date = DateTime.Now.ToString("yyyyMMdd"); //текущая дата
                        int time = Convert.ToInt32(DateTime.Now.ToString("HHmmss"));   //текущая дата
                        int lasttime = time; //время последней сделки
                        DateTime curTime = DateTime.Now; ; // текущее время
                        DateTime runTime = DateTime.Now; // время запуска системы, точка отсчета
                        DateTime FinishTime = DateTime.Now.AddHours(23 - runTime.Hour).AddMinutes(59 - runTime.Minute).AddSeconds(-curTime.Second); // устанавливаем время 23:00

                        int timeFrame = 1; // периодичность расчетов (минут)
                        int NextTfMinutes = (int)(Math.Truncate((double)(runTime.Minute / timeFrame))) * timeFrame + timeFrame; //получаем след период. например 32 минуты для 5минтки след период 35
                        DateTime NextTime = runTime.AddMinutes(NextTfMinutes - runTime.Minute).AddSeconds(-runTime.Second); // время следующей свечи по окончанию текущего часа



                        // cmd.CommandText = "TRUNCATE TABLE signal_temp_copy";
                        // cmd.ExecuteNonQuery();

                        //myAdapter.InsertCommand = cmd;

                        //            DateTime time = DateTime.Now;
                        //int hour = time.Hour;
                        //int minutes=time.Minute;
                        //if (hour <= 12)
                        //    Console.WriteLine("Good morning");
                        //else if (hour >= 12 && minutes >= 1)

                        short_long = "";
                        string comment = "", HourOrder = "";
                        decimal SummBuy = 0, SummSell = 0, HourPrice = 0, MaxBuyVol = 0, MaxSellVol = 0, MaxBuyPrice = 0, MaxSellPrice = 0;  
                        string Vector = "0";
                        int VolMaxHour = 0;
                        DateTime MaxTime = curTime;


                        //int k = 1;
                        //var format = new System.Globalization.NumberFormatInfo();
                        //format.NumberDecimalSeparator = ".";
                        while (curTime < FinishTime)
                        {
                            //curTime = time;
                            while (curTime < NextTime)
                            {
                                //SummBuy = 0; SummSell = 0; 
                                foreach (var qoute in trader.GetMarketDepth(_sec2))
                                {
                                    if (Convert.ToString(qoute.OrderDirection) == "Sell") { if (qoute.Volume > MaxSellVol) { MaxSellVol = qoute.Volume; MaxSellPrice = qoute.Price; } }
                                    if (Convert.ToString(qoute.OrderDirection) == "Buy") { if (qoute.Volume > MaxBuyVol) { MaxBuyVol = qoute.Volume; MaxBuyPrice = qoute.Price; } }

                                    if (qoute.Volume > VolMaxHour) // после тестирования убрать знак =
                                    //if (qoute.Volume >= VolMaxHour && HourPrice != qoute.Price) 
                                    {
                                        VolMaxHour = (int)qoute.Volume;
                                        HourPrice = qoute.Price;
                                        HourOrder = Convert.ToString(qoute.OrderDirection);
                                        MaxTime = DateTime.Now;
                                        SummSell = 0; SummBuy = 0;
                                        foreach (var qoute2 in trader.GetMarketDepth(_sec2))
                                        {
                                            if (Convert.ToString(qoute2.OrderDirection) == "Sell") { SummSell += qoute2.Volume; }
                                            if (Convert.ToString(qoute2.OrderDirection) == "Buy") { SummBuy += qoute2.Volume; }
                                        }
                                        if (VolMaxHour > VolsecCode) { Vector = Convert.ToString(Math.Round(SummSell / SummBuy, 2));  goto ExtraSendMessage; }
                                        Console.WriteLine("{0} {1} Мегазаявки {2} {3} Объем {4} Цена {5}", date, MaxTime.ToString("HH:mm"), _sec2, qoute.OrderDirection, qoute.Volume, qoute.Price);
                                        //Console.WriteLine("{0}  {1} бест бид прайс {2}", curTime, NextTime, qoute.ExtensionInfo[DdeQuoteColumns.Volatility]);
                                    }


                                }
                                Thread.Sleep(10000); //ждем 10 секунд
                                curTime = DateTime.Now;
                            }
                            Vector = Convert.ToString(Math.Round(SummSell / SummBuy, 2));
                            Console.WriteLine("Запись в базу истории {0} ... Следующая запись в {1}  вектор {2} цена {3}", curTime, NextTime, Vector, Convert.ToString(HourPrice));

                            if (HourOrder == "Sell") short_long = "-1"; else short_long = "1";
                            comment = "макс объем за период " + VolMaxHour + " в " + MaxTime;
                            cmd.CommandText = "INSERT INTO `history_glass` (`seccode`,`date`,`time`,`short_long`,`price`,`vol`,`maxbuyvol`,`maxsellvol`,`maxbuyprice`,`maxsellprice`,`vector`,`comments`,`type`,`time_frame`) "
                                                + "VALUES ('"
                                                + secCode + "','"
                                                + date + "','"
                                                + NextTime.ToString("HHmmss") + "','"
                                                + short_long + "','"
                                                + Convert.ToString(HourPrice).Replace(',', '.') + "','"
                                                + Convert.ToString(VolMaxHour) + "','"
                                                + Convert.ToString(MaxBuyVol).Replace(',', '.') + "','"
                                                + Convert.ToString(MaxSellVol).Replace(',', '.') + "','"
                                                + Convert.ToString(MaxBuyPrice).Replace(',', '.') + "','"
                                                + Convert.ToString(MaxSellPrice).Replace(',', '.') + "','"
                                                
                                                
                                                + Vector.Replace(',', '.') + "','"  // вектор меняем , на . для записи в базу дробных чисел
                                                + comment + "','"
                                                + "glass" + "','"
                                                + Convert.ToString(timeFrame)
                                                + "')";
                            cmd.ExecuteNonQuery();

                            // Thread.Sleep(30000); //ждем 10 секунд. после теста убрать

                            NextTfMinutes = (int)(Math.Truncate((double)(curTime.Minute / timeFrame))) * timeFrame + timeFrame; //вычисляем минуты следующего периода
                            NextTime = curTime.AddMinutes(NextTfMinutes - curTime.Minute).AddSeconds(-curTime.Second);  // добавляем TimeFrame и убираем возможную погрешность в минутах и секундах
                        
                        ExtraSendMessage: // метка для экстренного вывода сигнала
                        
                            if (VolMaxHour > VolsecCode)
                            {
                                Console.WriteLine("Запись в базу сигналов{0} ... Следующая запись в {1}", curTime, NextTime);
                                VolsecCode = (int)VolMaxHour;
                                //Vector = Math.Round(SummSell/SummBuy, 2);

                                if (HourOrder == "Sell") short_long = "-1"; else short_long = "1";
                                comment = "Мегозаявка " + HourOrder + ", объем " + VolMaxHour + ". Всего на покупку " + SummBuy + ". Всего на продажу " + SummSell + ". Вектор " + Vector + "." + " =-O";
                                cmd.CommandText = "INSERT INTO `signal_temp` (`seccode`,`date`,`time`,`signal`,`short_long`,`forces`,`price`,`comments`,`type`,`time_frame`,`sent`) "
                                                    + " VALUES ('"
                                                    + secCode + "','"
                                                    + date + "','"
                                                    + MaxTime.ToString("HHmmss") + "','"
                                                    + "glass" + "','"
                                                    + short_long + "','"
                                                    + "0" + "','"
                                                    + Convert.ToString(HourPrice).Replace(',', '.') + "','"
                                                    + comment + "','"
                                                    + "glass" + "','"
                                                    + "60" + "','" //пока ставим 60, так как сигналы приходят по 60 в подписке, потом можно поменять на timeFrame
                                                    + "0"
                                                    + "')";
                                cmd.ExecuteNonQuery();
                            }
                            VolMaxHour = 0;
                            MaxSellVol = 0;
                            MaxBuyVol = 0;

                            //Thread.Sleep(60000); //ждем 60 секунд
                        }
                        // останавливаем экспорт по DDE
                        trader.StopExport(trader.SecuritiesTable, trader.MyTradesTable, trader.EquityPositionsTable,
                                          trader.EquityPortfoliosTable, trader.OrdersTable);
                        Console.ReadKey();
                    }
                }
                //}
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);

            }
        }
    }
}